package de.fhin.mas.util;

import jade.core.AID;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import de.fhin.mas.MASEvents;
import de.fhin.mas.agents.MASBaseAgent;

/**
 * Bietet praktische Methoden zur Erzeugung von <tt>MessageTemplate</tt>s und
 * <tt>ACLMessage</tt>s.
 * 
 * @author Alexander Weickmann
 */
public final class MessageUtil {

	/**
	 * Gibt ein <tt>MessageTemplate</tt> zurueck, welches die grundlegenden
	 * Informationen matcht, die fuer eine Kommunikation noetig sein koennten.
	 * <p>
	 * Das <tt>MessageTemplate</tt> matcht das angegebene Protokoll, die
	 * angegebene Conversation-ID, das angegebene Performative und den
	 * angegebenen Sender.
	 * <p>
	 * Fuer die korrekte Uebergabe des Performative sind Aufrufer selbst
	 * verantwortlich. Protokoll und Conversation-ID und Sender sind optional
	 * und koennen <tt>null</tt> sein.
	 * 
	 * @param protocol
	 *            Das zu filternde Protokoll, darf <tt>null</tt> sein.
	 * @param conversationId
	 *            Die zu filternde Conversation-ID, darf <tt>null</tt> sein.
	 * @param performative
	 *            Das zu filternde Performative.
	 * @param sender
	 *            Der zu filternde Absender, darf <tt>null</tt> sein.
	 */
	public static MessageTemplate buildBasicCommunicationTemplate(String protocol, String conversationId,
			int performative, AID sender) {

		MessageTemplate returnTemplate = MessageTemplate.MatchPerformative(performative);

		if (protocol != null) {
			MessageTemplate protocolTemplate = MessageTemplate.MatchProtocol(protocol);
			returnTemplate = MessageTemplate.and(returnTemplate, protocolTemplate);
		}

		if (conversationId != null) {
			MessageTemplate conversationIdTemplate = MessageTemplate.MatchConversationId(conversationId);
			returnTemplate = MessageTemplate.and(returnTemplate, conversationIdTemplate);
		}

		if (sender != null) {
			MessageTemplate senderTemplate = MessageTemplate.MatchSender(sender);
			returnTemplate = MessageTemplate.and(returnTemplate, senderTemplate);
		}

		return returnTemplate;
	}

	/**
	 * Erzeugt eine <tt>ACLMessage</tt> mit den angegebenen Parametern.
	 * 
	 * @param protocol
	 *            Das zu verwendende Protokoll.
	 * @param conversationId
	 *            Die zu verwendende Conversation-ID.
	 * @param performative
	 *            Das zu verwendende Performative.
	 * @param receivers
	 *            Die Empfaenger der Nachricht.
	 */
	public static ACLMessage buildMessage(String protocol, String conversationId, int performative, AID[] receivers) {

		ACLMessage message = new ACLMessage(performative);
		if (receivers != null) {
			for (AID currentReceiver : receivers) {
				message.addReceiver(currentReceiver);
			}
		}
		message.setConversationId(conversationId);
		message.setProtocol(protocol);

		return message;
	}

	/**
	 * Setzen des Topics (z.B. new_order) einer Nachricht. Dadurch wird implizit
	 * eine Liste von Empfängern gesetzt, da alle Agenten, die sich für das
	 * Topic registriert haben die Nachricht erhalten.
	 * 
	 * @param sender
	 *            Absendender Agent.
	 * @param msg
	 *            Nachricht, für die das Topic gesetzt werden soll.
	 * @param topic
	 *            Das zu setzende Topic.
	 * 
	 * @author Ast
	 */
	public static void setMessageTopic(MASBaseAgent sender, ACLMessage msg, MASEvents topic) {
		AID topicRcv = sender.getSubscription(topic);
		msg.addReceiver(topicRcv);

		// TODO: Coversation-ID nicht mehr verwenden!
		msg.setConversationId(topic.getName());
	}

	/**
	 * Verhindert Instanzierung.
	 */
	private MessageUtil() {

	}

}
